package com.briup.demo.common.response;

import lombok.AccessLevel;
import lombok.Data;
import lombok.RequiredArgsConstructor;

import java.util.function.Function;

/**
 * 统一响应格式结果类；
 * 用于统一后端给前端返回的响应数据格式，
 * 便于前端获取和识别返回的响应是业务处理成功还是失败
 */
@Data
// @RequiredArgsConstructor注解能够让lombok自动生成一个构造器，
// 该构造器中的参数为本类中所有被final修饰的属性
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class Result<T> {
    /**
     * 给前端提供的业务处理响应状态码，用于标识业务处理成功还是失败
     */
    private final int code;
    /**
     * 给前端提供的业务处理 消息，主要是展示业务处理失败的原因
     */
    private final String message;
    /**
     * 是当业务处理成功时，给前端返回的数据所在
     */
    private final T data;

    private Result(int code, String message) {
        this(code, message, null);
    }

    /**
     * 成功时的响应结果构造方法，无响应数据；
     * 默认设置响应的消息为 成功
     *
     * @return 成功时的响应结果
     */
    public static Result<?> success() {
        ResultCode success = ResultCode.SUCCESS;
        return new Result<>(success.getCode(), success.getMessage());
    }

    /**
     * 成功时的响应结果构造方法，有响应数据；
     * 通过函数式接口的方式，实现根据不同的业务场景，返回不同的成功消息
     *
     * @param data 业务处理成功时，需要返回给前端的数据
     * @return 成功时的响应结果
     */
    public static <T> Function<String, Result<T>> success(T data) {
        // msg 参数是给 本方法的返回值Function实现类对象中的apply方法 传入的参数
        return msg -> new Result<>(200, msg, data);
    }

    /**
     * 失败时的响应结果构造方法，无响应数据；
     * 默认设置响应的状态码为 500，消息为 自定义失败消息
     *
     * @param message 业务处理失败时，需要返回给前端的失败消息
     * @return 失败时的响应结果
     */
    public static Result<?> fail(String message) {
        return fail(500, message);
    }

    /**
     * 失败时的响应结果构造方法，无响应数据；
     * 允许自定义响应的状态码和消息
     *
     * @param code    业务处理失败时，需要返回给前端的状态码
     * @param message 业务处理失败时，需要返回给前端的失败消息
     * @return 失败时的响应结果
     */
    public static Result<?> fail(int code, String message) {
        return new Result<>(code, message);
    }
}
